use std::str::FromStr;

use tauri::{AppHandle, Manager, State};
use tauri_plugin_global_shortcut::{GlobalShortcutExt, Shortcut};
use tauri_plugin_notification::NotificationExt;

use crate::{
    app_config::{AppConfig, Storage},
    screenshot_and_save::{self, SaveConfig},
    screenshot_local::ScreenTarget,
    types::TResult,
};

fn screenshot_local(app_handle: &AppHandle) -> TResult<()> {
    let state: State<Storage> = app_handle.state();
    let app_config = state
        .app_config
        .lock()
        .map_err(|_| "锁定 app_config 失败")?;
    let target = match app_config.local_screen_target.clone() {
        Some(target) => match target.as_str() {
            "all" => ScreenTarget::All,
            _ => ScreenTarget::Primary,
        },
        _ => ScreenTarget::Primary,
    };

    let message = app_handle.notification().builder().title("本地截图");
    let save_config = SaveConfig {
        save_type_list: app_config.save_type_list.clone(),
        save_path: app_config.save_path.clone(),
        auto_create_save_path: app_config.auto_create_save_path.clone(),
        img_save_type: app_config.img_save_type.clone(),
    };
    tokio::spawn(async move {
        let _ = match screenshot_and_save::screen_from_local(target, &save_config).await {
            Ok(_) => message.body("截图成功").show(),
            Err(e) => message.body(e.to_string()).show(),
        };
    });
    Ok(())
}

fn screenshot_remote(app_handle: &AppHandle) -> TResult<()> {
    let state: State<Storage> = app_handle.state();
    let app_config = state
        .app_config
        .lock()
        .map_err(|_| "锁定 app_config 失败")?;
    let message = app_handle.notification().builder().title("远程截图");
    let save_config = SaveConfig {
        save_type_list: app_config.save_type_list.clone(),
        save_path: app_config.save_path.clone(),
        auto_create_save_path: app_config.auto_create_save_path.clone(),
        img_save_type: app_config.img_save_type.clone(),
    };
    if let Some(addr) = app_config.remote_address.clone() {
        tokio::spawn(async move {
            let res = screenshot_and_save::screen_from_remote(addr, &save_config).await;
            let _ = match res {
                Ok(_) => message.body("截图成功").show(),
                Err(e) => message.body(e.to_string()).show(),
            };
        });
    } else {
        let _ = message.body("截图失败，远程截图地址不正确").show();
    }
    Ok(())
}

pub fn shortcut_handler(app_handle: &AppHandle, shortcut: &Shortcut) {
    let state: State<Storage> = app_handle.state();
    let shortcut_map = state.shortcut_map.lock();
    if let Ok(shortcut_map) = shortcut_map {
        if let Some(handler) = shortcut_map.get(shortcut) {
            let _ = handler(app_handle);
        }
    }
}

pub fn init(app_handle: &AppHandle, config: &AppConfig) -> TResult<()> {
    let state: tauri::State<Storage> = app_handle.state();
    let mut shortcut_map = state
        .shortcut_map
        .lock()
        .map_err(|_| "锁定 shortcut_map 失败")?;
    let global_shortcut = app_handle.global_shortcut();
    let old_shortcut_list: Vec<Shortcut> = shortcut_map.keys().map(|shortcut| *shortcut).collect();
    global_shortcut
        .unregister_all(old_shortcut_list)
        .map_err(|_| "注销旧的快捷键失败")?;
    shortcut_map.clear();
    if let Some(local_hotkey) = &config.local_hotkey {
        if !local_hotkey.is_empty() {
            let shortcut =
                Shortcut::from_str(&local_hotkey).map_err(|_| "格式化本地截图快捷键失败")?;
            global_shortcut.register(shortcut)?;
            shortcut_map.insert(shortcut, screenshot_local);
        }
    }

    if let Some(remote_hotkey) = &config.remote_hotkey {
        if !remote_hotkey.is_empty() {
            let shortcut =
                Shortcut::from_str(&remote_hotkey).map_err(|_| "格式化远程截图快捷键失败")?;
            global_shortcut.register(shortcut)?;
            shortcut_map.insert(shortcut, screenshot_remote);
        }
    }

    Ok(())
}
